package com.horay.springclouddemo.sentinel.client.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 熔断控制器
 *
 * @author heyingcheng
 * @date 2020/4/4 17:33
 */
@Slf4j
@RestController
@RequestMapping("sentinel/circuit/breaker")
public class CircuitBreakerController {

    @GetMapping("methodA")
    @SentinelResource(
            // 若blockHandler和fallback都进行了配置，
            // 则被限流降级而抛出BlockException时只会进入blockHandler处理逻辑。
            value = "methodA",
            // 负责Sentinel控制台配置违规, 流控规则
            blockHandler="methodABlockHandler",
            // 负责业务异常, 降级规则
            fallback = "methodAFallback",
            exceptionsToTrace = Exception.class
    )
    public ResponseEntity methodA(@RequestParam Integer param0, @RequestParam String param1) {
        log.info("com.horay.springclouddemo.sentinel.client.controller.CircuitBreakerController.methodA, param0:[{}], param1:[{}]", param0, param1);
        Integer v = 1 / param0;
        return ResponseEntity.ok().body(CircuitBreakerController.class.getName().concat(".methodA").concat("=").concat(String.valueOf(v)));
    }

    public ResponseEntity methodABlockHandler(Integer param0, String param1, BlockException e) {
        log.error("com.horay.springclouddemo.sentinel.client.controller.CircuitBreakerController.methodABlockHandler, param0:[{}], param1:[{}]", param0, param1, e);
        return ResponseEntity.ok().body(CircuitBreakerController.class.getName().concat(".methodABlockHandler"));
    }

    public ResponseEntity methodAFallback(Integer param0, String param1) {
        log.error("com.horay.springclouddemo.sentinel.client.controller.CircuitBreakerController.methodAFallback, param0:[{}], param1:[{}]", param0, param1);
        return ResponseEntity.unprocessableEntity().body(CircuitBreakerController.class.getName().concat(".methodAFallback"));
    }

}
